#include "Grammar.h"

#define tolerance 5

Grammar::Grammar(CComPtr<ISpRecoGrammar> cpGram){
	this->cpGram=cpGram;
}

Grammar::~Grammar(void){
	free(cpGram);
}


void Grammar::init(void){
	//this->defineDirections(); //Not used
	this->defineStart();
	this->defineStop();
	this->defineReset();
	this->definePause();
	this->defineResume();
	this->defineConfirm();
	this->defineRunTimeCommands();
}

void Grammar::defineRunTimeCommands(void){
	hr = cpGram->GetRule(L"GRAB", RULE_RUNTIME_GRAB, SPRAF_TopLevel | SPRAF_Active, TRUE, &hRunTimeCommands);
	hr = cpGram->AddWordTransition(hRunTimeCommands, NULL, L"Pick", L" ", SPWT_LEXICAL, 1, NULL);
	if(tolerance>5)
	hr = cpGram->AddWordTransition(hRunTimeCommands, NULL, L"Grab", L" ", SPWT_LEXICAL, 1, NULL);

	
	hr = cpGram->GetRule(L"GO", RULE_RUNTIME_GO, SPRAF_TopLevel | SPRAF_Active, TRUE, &hRunTimeCommands);
	if(tolerance>5)
	hr = cpGram->AddWordTransition(hRunTimeCommands, NULL, L"Release", L" ", SPWT_LEXICAL, 1, NULL);
	if(tolerance>5)
	hr = cpGram->AddWordTransition(hRunTimeCommands, NULL, L"Throw", L" ", SPWT_LEXICAL, 1, NULL);
	hr = cpGram->AddWordTransition(hRunTimeCommands, NULL, L"Go", L" ", SPWT_LEXICAL, 1, NULL);
}

void Grammar::defineStart(void){
	hr = cpGram->GetRule(L"START", RULE_START_GAME, SPRAF_TopLevel | SPRAF_Active, TRUE, &hStartGame_First);
	hr = cpGram->CreateNewState(hStartGame_First, &hStartGame_Second);

	//Optional
	if(tolerance>7)
	hr = cpGram->AddWordTransition(hStartGame_First, hStartGame_First, L"Please", L" ", SPWT_LEXICAL, 1, NULL);

	hr = cpGram->AddWordTransition(hStartGame_First, hStartGame_Second, L"Start", L" ", SPWT_LEXICAL, 1, NULL);
	hr = cpGram->AddWordTransition(hStartGame_First, NULL, L"Start", L" ", SPWT_LEXICAL, 1, NULL);
	if(tolerance>5)
	hr = cpGram->AddWordTransition(hStartGame_First, hStartGame_Second, L"Launch", L" ", SPWT_LEXICAL, 1, NULL);
	if(tolerance>7)
	hr = cpGram->AddWordTransition(hStartGame_First, hStartGame_Second, L"Set up", L" ", SPWT_LEXICAL, 1, NULL);

	//Optional
	if(tolerance>3)
	hr = cpGram->AddWordTransition(hStartGame_Second, hStartGame_Second, L"New", L" ", SPWT_LEXICAL, 1, NULL);

	if(tolerance>3)
	hr = cpGram->AddWordTransition(hStartGame_Second, NULL, L"Game", L" ", SPWT_LEXICAL, 1, NULL);
	if(tolerance>7)
	hr = cpGram->AddWordTransition(hStartGame_Second, NULL, L"Play", L" ", SPWT_LEXICAL, 1, NULL);
}

void Grammar::defineStop(void){
	hr = cpGram->GetRule(L"STOP", RULE_STOP_GAME, SPRAF_TopLevel | SPRAF_Active, TRUE, &hStopGame_First);
	hr = cpGram->CreateNewState(hStopGame_First, &hStopGame_Second);

	//Optional
	if(tolerance>7)
	hr=cpGram->AddWordTransition(hStopGame_First, hStopGame_First, L"Please", L" ", SPWT_LEXICAL, 1, NULL);

	//if(tolerance>5)
	hr=cpGram->AddWordTransition(hStopGame_First, hStopGame_Second, L"Exit", L" ", SPWT_LEXICAL, 1, NULL);
	hr=cpGram->AddWordTransition(hStopGame_First, NULL, L"Exit", L" ", SPWT_LEXICAL, 1, NULL);
	hr=cpGram->AddWordTransition(hStopGame_First, hStopGame_Second, L"Quit", L" ", SPWT_LEXICAL, 1, NULL);
	hr=cpGram->AddWordTransition(hStopGame_First, NULL, L"Quit", L" ", SPWT_LEXICAL, 1, NULL);
	if(tolerance>5)
	hr=cpGram->AddWordTransition(hStopGame_First, hStopGame_Second, L"Abort", L" ", SPWT_LEXICAL, 1, NULL);

	
	if(tolerance>3)
	hr=cpGram->AddWordTransition(hStopGame_Second, NULL, L"Game", L" ", SPWT_LEXICAL, 1, NULL);
	if(tolerance>7)
	hr=cpGram->AddWordTransition(hStopGame_Second, NULL, L"Play", L" ", SPWT_LEXICAL, 1, NULL);
}

void Grammar::definePause(void){
	hr = cpGram->GetRule(L"PAUSE", RULE_PAUSE_GAME, SPRAF_TopLevel | SPRAF_Active, TRUE, &hPauseGame_First);
	hr = cpGram->CreateNewState(hPauseGame_First, &hPauseGame_Second);

	//Optional
	if(tolerance>7)
	hr=cpGram->AddWordTransition(hPauseGame_First, hPauseGame_First, L"Please", L" ", SPWT_LEXICAL, 1, NULL);

	if(tolerance>5)
	hr=cpGram->AddWordTransition(hPauseGame_First, hPauseGame_Second, L"Interrupt", L" ", SPWT_LEXICAL, 1, NULL);
	hr=cpGram->AddWordTransition(hPauseGame_First, hPauseGame_Second, L"Pause", L" ", SPWT_LEXICAL, 1, NULL);

	//Optional
	if(tolerance>7)
	hr = cpGram->AddWordTransition(hPauseGame_Second, hPauseGame_Second, L"the", L" ", SPWT_LEXICAL, 1, NULL);
	if(tolerance>3)
	hr=cpGram->AddWordTransition(hPauseGame_Second, NULL, L"Game", L" ", SPWT_LEXICAL, 1, NULL);
	if(tolerance>7)
	hr=cpGram->AddWordTransition(hPauseGame_Second, NULL, L"Play", L" ", SPWT_LEXICAL, 1, NULL);
}

void Grammar::defineResume(void){
	hr = cpGram->GetRule(L"RESUME", RULE_RESUME_GAME, SPRAF_TopLevel | SPRAF_Active, TRUE, &hResumeGame_First);
	hr = cpGram->CreateNewState(hResumeGame_First, &hResumeGame_Second);

	//Optional
	if(tolerance>7)
	hr=cpGram->AddWordTransition(hResumeGame_First, hResumeGame_First, L"Please", L" ", SPWT_LEXICAL, 1, NULL);

	
	hr=cpGram->AddWordTransition(hResumeGame_First, hResumeGame_Second, L"Resume", L" ", SPWT_LEXICAL, 1, NULL);
	if(tolerance>3)
	hr=cpGram->AddWordTransition(hResumeGame_First, hResumeGame_Second, L"Continue", L" ", SPWT_LEXICAL, 1, NULL);

	//Optional
	if(tolerance>7)
	hr = cpGram->AddWordTransition(hResumeGame_Second, hResumeGame_Second, L"the", L" ", SPWT_LEXICAL, 1, NULL);

	if(tolerance>3)
	hr=cpGram->AddWordTransition(hResumeGame_Second, NULL, L"Game", L" ", SPWT_LEXICAL, 1, NULL);
	if(tolerance>7)
	hr=cpGram->AddWordTransition(hResumeGame_Second, NULL, L"Play", L" ", SPWT_LEXICAL, 1, NULL);
}


void Grammar::defineReset(void){
	hr = cpGram->GetRule(L"RESET", RULE_RESET_GAME, SPRAF_TopLevel | SPRAF_Active, TRUE, &hResetGame_First);
	hr = cpGram->CreateNewState(hResetGame_First, &hResetGame_Second);

	//Optional
	if(tolerance>7)
	hr=cpGram->AddWordTransition(hResetGame_First, hResetGame_First, L"Please", L" ", SPWT_LEXICAL, 1, NULL);


	hr=cpGram->AddWordTransition(hResetGame_First, hResetGame_Second, L"Reset", L" ", SPWT_LEXICAL, 1, NULL);
	if(tolerance>3)
	hr=cpGram->AddWordTransition(hResetGame_First, hResetGame_Second, L"Relaunch", L" ", SPWT_LEXICAL, 1, NULL);

	//Optional
	if(tolerance>7)
	hr = cpGram->AddWordTransition(hResetGame_Second, hResetGame_Second, L"the", L" ", SPWT_LEXICAL, 1, NULL);
	if(tolerance>7)
	hr = cpGram->AddWordTransition(hResetGame_Second, hResetGame_Second, L"this", L" ", SPWT_LEXICAL, 1, NULL);

	if(tolerance>3)
	hr=cpGram->AddWordTransition(hResetGame_Second, NULL, L"Game", L" ", SPWT_LEXICAL, 1, NULL);
	if(tolerance>7)
	hr=cpGram->AddWordTransition(hResetGame_Second, NULL, L"Play", L" ", SPWT_LEXICAL, 1, NULL);
}

void Grammar::defineDirections(void){
	hr = cpGram->GetRule(L"Up", RULE_DIRECTION_UP, SPRAF_TopLevel | SPRAF_Active, TRUE, &hDirection);
	hr = cpGram->AddWordTransition(hDirection, NULL, L"Up", L" ", SPWT_LEXICAL, 1, NULL);

	hr = cpGram->GetRule(L"Down", RULE_DIRECTION_DOWN, SPRAF_TopLevel | SPRAF_Active, TRUE, &hDirection);
	hr = cpGram->AddWordTransition(hDirection, NULL, L"Down", L" ", SPWT_LEXICAL, 1, NULL);

	hr = cpGram->GetRule(L"Left", RULE_DIRECTION_LEFT, SPRAF_TopLevel | SPRAF_Active, TRUE, &hDirection);
	hr = cpGram->AddWordTransition(hDirection, NULL, L"Left", L" ", SPWT_LEXICAL, 1, NULL);

	hr = cpGram->GetRule(L"Right", RULE_DIRECTION_RIGHT, SPRAF_TopLevel | SPRAF_Active, TRUE, &hDirection);
	hr = cpGram->AddWordTransition(hDirection, NULL, L"Right", L" ", SPWT_LEXICAL, 1, NULL);
}

void Grammar::defineConfirm(void){
	hr = cpGram->GetRule(L"Confirm", RULE_CONFIRM, SPRAF_TopLevel | SPRAF_Active, TRUE, &hConfirm);
	hr = cpGram->AddWordTransition(hConfirm, NULL, L"Confirm", L" ", SPWT_LEXICAL, 1, NULL);
	if(tolerance>3)
	hr = cpGram->AddWordTransition(hConfirm, NULL, L"Yes", L" ", SPWT_LEXICAL, 1, NULL);
	if(tolerance>5)
	hr = cpGram->AddWordTransition(hConfirm, NULL, L"Affirm", L" ", SPWT_LEXICAL, 1, NULL);


	hr = cpGram->GetRule(L"Cancel", RULE_CANCEL, SPRAF_TopLevel | SPRAF_Active, TRUE, &hCancel);
	hr = cpGram->AddWordTransition(hCancel, NULL, L"Cancel", L" ", SPWT_LEXICAL, 1, NULL);
	if(tolerance>3)
	hr = cpGram->AddWordTransition(hCancel, NULL, L"No", L" ", SPWT_LEXICAL, 1, NULL);
	if(tolerance>5)
	hr = cpGram->AddWordTransition(hCancel, NULL, L"Stop", L" ", SPWT_LEXICAL, 1, NULL);
}

